package com.dnzx.util;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * @CladdName MyFileUtil
 * @Description:
 * @auther: WuCB
 * @Date: 2018/12/25 09:53
 */
public class MyFileUtil {


    /**
     * 方法一：单文件上传，通过file.transferTo()方法写入磁盘
     * @param file  jsp页面传入的参数name="file"
     * @param localPath  本地存放路径，例如：linux下 savePath = "/usr/local/upload/" ，Windows下 E://usr/local/upload/ . tomcat需要配置虚拟路径去访问
     * @param fileTypeParam  外部传入上传文件类型
     * @return 返回本地存放路径
     * @throws Exception
     */
    public static String fileUpload(MultipartFile file,String fileTypeParam, String localPath ) throws Exception{
        //原始图片名称
        String originalFilename = file.getOriginalFilename();
        //存放本地的文件名称
        String fileName = null;
        try{
            //判断是否有上传文件
            if( file != null && originalFilename != null && originalFilename.length()>0 ){
                //文件类型
                String fileType = originalFilename.substring(originalFilename.lastIndexOf(".")+1);
                if(fileTypeParam != null && !fileTypeParam.isEmpty() &&
                        !"undefined".equals(fileTypeParam) && !fileTypeParam.equals(fileType)){
                    throw new Exception("请上传"+fileTypeParam+"格式文件");
                }
                //新建文件目录
                File f = new File(localPath);
                //如果目录不存在，新建文件目录
                if(!f.exists()){
                    f.mkdirs();
                }
                //获取系统当前时间
                Date date = new Date();
                //日期格式化
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                String time = format.format(date);
                //上传文件真正名称
                fileName = UUID.randomUUID() + "_" + time
                        + originalFilename.substring(originalFilename.lastIndexOf(".")) ;
                //创建文件
                File newFile = new File(localPath + File.separator + fileName);

                //将内存的数据写入磁盘
                file.transferTo(newFile);
            }
            return localPath + fileName ;
        }catch(Exception e){
            e.printStackTrace();
            throw new Exception("上传失败！");
        }
    }


    /**
     *  文件下载
     * @param filePath 存储路径+完整文件名
     * @param fileName 导出文件名
     * @param delFile  是否删除文件
     * @param response
     * @throws Exception
     */
    public static void fileDownload(String filePath,String fileName,boolean delFile,HttpServletResponse response) throws Exception{
        response.setCharacterEncoding("UTF-8");
        //获取数据库保存的文件名称
        File file = new File(filePath);
//        String NewFileName = file.getName();
        String NewPath = file.getPath();
        //第一步：设置响应类型 ,应用程序强制下载
        response.setContentType("application/force-download");
        //第二读取文件
        InputStream in = new FileInputStream(NewPath);
//        //设置响应头，对文件进行url编码 ()
//        NewFileName = java.net.URLEncoder.encode(fileName,"UTF-8");
        //设置下载的文件名称,可直接设置为中文名称，不需要进行转码
        response.setHeader("Content-Disposition", "attachment;filename="+fileName);
        response.setContentLength(in.available());
        //第三步：老套路，开始copy
        OutputStream out = response.getOutputStream();
        byte[] b = new byte[1024];
        int len = 0;
        while((len = in.read(b))!=-1){
            out.write(b, 0, len);
        }
        out.flush();
        out.close();
        in.close();
        //删除原文件s
        if(delFile){
            file.delete();
        }
    }

    /**
     * 文件流本地创建json文件
     * @param jsonString 字符串
     * @param filePath 文件存放路径
     * @param fileName 完整文件名（包含后缀） eg: **.json , **.txt
     * @return
     */
    public static boolean createJsonFile(String jsonString, String filePath, String fileName) {
        // 标记文件生成是否成功
        boolean flag = true;

        // 拼接文件完整路径
        String fullPath = filePath + File.separator + fileName ;

        // 生成json格式文件
        try {
            // 保证创建一个新文件
            File file = new File(fullPath);
            // 如果父目录不存在，创建父目录
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            // 如果已存在,删除旧文件
            if (file.exists()) {
                file.delete();
            }
            file.createNewFile();

            // 格式化json字符串
            jsonString = JsonFormatTool.formatJson(jsonString);

            // 将格式化后的字符串写入文件
            Writer write = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
            write.write(jsonString);
            write.flush();
            write.close();
        } catch (Exception e) {
            flag = false;
            e.printStackTrace();
        }
        // 返回是否成功的标记
        return flag;
    }


    /**
     * 功能：Java读取txt文件的内容
     * 步骤：1：先获得文件句柄
     * 2：获得文件句柄当做是输入一个字节码流，需要对这个输入流进行读取
     * 3：读取到输入流后，需要读取生成字节流
     * 4：一行一行的输出。readline()。
     * 备注：需要考虑的是异常情况
     * @param filePath 完整的文件访问路径（包含文件后缀）
     * @return 返回文本字符串信息
     */
    public static String readTxtFile(String filePath) throws Exception{
        try {
            String encoding="UTF-8";
            File file=new File(filePath);
            //判断文件是否存在
            if(file.isFile() && file.exists()){
                //考虑到编码格式
                InputStreamReader read = new InputStreamReader(new FileInputStream(file),encoding);
                BufferedReader bufferedReader = new BufferedReader(read);
                //单线程用StringBuilder速度快
                StringBuilder jsonStr = new StringBuilder();
//                StringBuffer jsonStr = new StringBuffer() ; // 多线程读取用这个方法
                String lineTxt = null;
                while((lineTxt = bufferedReader.readLine()) != null){
                    jsonStr.append(lineTxt);
                    jsonStr.append("\n");
                }
                read.close();
                bufferedReader.close();
                return jsonStr.toString();
            }else{
                throw new Exception("找不到指定的文件");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("读取文件内容出错" + e.getMessage());
        }
    }
}
